/**
 * FileContentManager is a Java based file manager desktop application, it can
 * show, edit and manipulate the content of the files archived inside a zip.
 * 
 * Copyright (C) 2007
 * 
 * Created by Camila Sanchez [http://mimix.wordpress.com/], Rafael Naufal
 * [http://rnaufal.livejournal.com] and Rodrigo [rdomartins@gmail.com]
 * 
 * FileContentManager is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by the
 * Free Software Foundation; either version 2.1 of the License, or (at your
 * option) any later version.
 * 
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with FileContentManager; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
/*
 * Created on 22/05/2007 22:30:23
 */
package br.com.jteam.jfcm.model.services.impl;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import br.com.jteam.jfcm.model.File;
import br.com.jteam.jfcm.model.FileHistory;
import br.com.jteam.jfcm.model.FileType;
import br.com.jteam.jfcm.model.factory.FileFactory;
import br.com.jteam.jfcm.model.services.FileHistoryService;
import br.com.jteam.jfcm.model.services.FileListContentService;
import br.com.jteam.jfcm.model.services.exception.CorruptedZipFileException;
import br.com.jteam.jfcm.model.services.exception.FileListContentServiceException;
import br.com.jteam.jfcm.model.services.exception.IncorrectFileExtensionException;
import br.com.jteam.jfcm.model.util.FileTypeUtil;
import br.com.jteam.jfcm.model.validator.FileExtensionValidator;
import br.com.jteam.jfcm.model.validator.impl.ZipFileExtensionValidator;

/**
 * <p>
 * Implementa&ccedil;&atilde;o respons&aacute;vel por manipular arquivos
 * {@link br.com.jteam.jfcm.model.FileType#ZIP}
 * 
 * @author Rafael Naufal <rafael.naufal@gmail.com>
 * @since 1.0
 * @version $Id$
 */
public class FileListContentServiceImpl implements FileListContentService
{
	/**
	 * <p>
	 * Refer&ecirc;ncia para o servi&ccedil;o do hist&oacute;rico de arquivos.
	 */
	private FileHistoryService fileHistoryService;

	/**
	 * <p>
	 * Construtor.
	 * 
	 * @param fileHistoryService -
	 *            servi&ccedil;o de hist&oacute;rico de arquivos.
	 * @throws IllegalArgumentException -
	 *             Caso o servi&ccedil;o do hist&oacute;rico de arquivos seja
	 *             nulo.
	 */
	public FileListContentServiceImpl(FileHistoryService fileHistoryService)
	{
		if (fileHistoryService == null)
		{
			throw new IllegalArgumentException("File History Service cannot be null");
		}
		this.fileHistoryService = fileHistoryService;
	}

	/**
	 * <p>
	 * Lista os arquivos que s&atilde;o conte&uacute;do de um arquivo
	 * {@link br.com.jteam.jfcm.model.FileType#ZIP}
	 * 
	 * @param file -
	 *            arquivo .ZIP a ser aberto
	 * @return - uma inst�ncia da classe <code>ZipFile</code>, contendo uma
	 *         lista de <code>File</code>.
	 * @throws FileListContentServiceException -
	 *             Caso o arquivo seja nulo ou n&atilde;o seja um arquivo
	 *             {@link br.com.jteam.jfcm.model.FileType#ZIP}
	 * @see br.com.jteam.jfcm.model.services.FileListContentService#openZipContent(java.io.File)
	 */
	public File openZipContent(java.io.File file) throws FileListContentServiceException
	{
		ZipInputStream zipInputStream;
		try
		{
			File zipFile = createZipFile(file);
			zipInputStream =
							new ZipInputStream(new FileInputStream(zipFile.getPath()));
			ZipEntry zipEntry;
			while ((zipEntry = zipInputStream.getNextEntry()) != null)
			{
				String fileName = zipEntry.getName();
				System.out.println("");
				br.com.jteam.jfcm.model.File fileInZip =
								FileFactory	.getInstance(FileType.DEFAULT)
											.createFile(fileName,
														zipFile.getPath());
				zipFile.add(fileInZip);
				zipInputStream.closeEntry();
			}
			zipInputStream.close();
			fileHistoryService.addToHistory(zipFile);
			return zipFile;
		} catch (IncorrectFileExtensionException ex)
		{
			throw new FileListContentServiceException(ex);
		} catch (FileNotFoundException ex)
		{
			throw new FileListContentServiceException(	"Error in input/output",
														ex);
		} catch (IOException ex)
		{
			throw new FileListContentServiceException(	"Error in input/output",
														ex);
		} catch (CorruptedZipFileException ex)
		{
			throw new FileListContentServiceException(ex);
		}
	}

	/**
	 * <p>
	 * Retorna o hist&oacute;rico de arquivos.
	 * 
	 * @return hist&oacute;rico de arquivos.
	 * @see br.com.jteam.jfcm.model.services.FileListContentService#getHistory()
	 */
	public FileHistory getHistory()
	{
		return fileHistoryService.getHistory();
	}

	private File createZipFile(java.io.File file) throws IncorrectFileExtensionException,
					FileListContentServiceException
	{
		if (file == null)
		{
			throw new IllegalArgumentException("Zip File cannot be null");
		}
		if (!FileTypeUtil.isFilePresentOnDisk(file.getAbsolutePath()))
		{
			throw new FileListContentServiceException("File doesn't exist anymore on disc");
		}
		FileExtensionValidator fileExtensionValidator =
						new ZipFileExtensionValidator();
		fileExtensionValidator.validate(file.getName());
		FileType fileType = FileType.getFileTypeByFileName(file.getName());
		return FileFactory	.getInstance(fileType)
							.createFile(file.getName(), file.getAbsolutePath());
	}
}
